#include "data_struct/base/TimeWorkBase/EventBase/OccurFailure.hpp"

namespace behavior_controller {
namespace occur {

OccurFailure::OccurFailure() : signal_ready_(false) {}

void OccurFailure::PushHandler(std::function<void()> handler) {
    {
        boost::lock_guard<boost::mutex> lock(buffer_mtx_);
        receive_buffer_.push(handler);
    }
    Notify();
}

void OccurFailure::HandleEvents() {
    if (Wait()) {
        ProcessEvents();
    }
}

void OccurFailure::Clear() {
    boost::lock_guard<boost::mutex> lock(register_mtx_);
    for (auto &it : registered_signals_) {
        it.second.disconnect();
    }
    registered_signals_.clear();
}

void OccurFailure::ProcessEvents() {
    {
        boost::lock_guard<boost::mutex> lock(buffer_mtx_);
        if (receive_buffer_.empty())
            return;

        work_buffer_.swap(receive_buffer_);
    }
    while (!work_buffer_.empty()) {
        auto &work_func = work_buffer_.front();
        work_func();
        work_buffer_.pop();
    }
}

void OccurFailure::Notify() {
    {
        boost::lock_guard<boost::mutex> lock(signal_mtx_);
        signal_ready_ = true;
    }
    signal_cond_.notify_one();
}

bool OccurFailure::Wait() {
    boost::unique_lock<boost::mutex> lock(signal_mtx_);
    //阻塞当前线程，直到条件变量被唤醒，或到指定时限时长后
    if (signal_cond_.wait_for(lock, boost::chrono::seconds(1),
                              [this] { return signal_ready_; }))
    {
        signal_ready_ = false;
        return true;
    }
    return false;
}

} // namespace occur
} // namespace behavior_controller
